<?

class bf_path {

	public static function expand($path) {
		$names = explode('/', preg_replace("/\\\\+/", '/', realpath(preg_replace("/\\\\+/", '/', $path))));
		$res = '';
		foreach ($names as $name) {
			if ($name !== '') {
				$res .= '/' . $name;
				if (is_link($res)) {
					$res = preg_replace('/\/+$/', '', preg_replace("/\\\\+/", '/', readlink($res)));
				}
			}
		}
		return $res;
	}

	public static function concat($p1, $p2) {
		return preg_replace('/\/+$/', '', preg_replace("/\\\\+/", '/', $p1))
			. '/' . preg_replace('/^\/+/', '', preg_replace("/\\\\+/", '/', $p2));
	}

	public static function inside($path, $root, $expanded = false) {
		if ($expanded) {
			$r = $root;
			$p = $path;
		} else {
			$r = bf_path::expand($root);
			$p = bf_path::expand($path);
		}
		$rlen = mb_strlen($r, 'utf-8');
		$plen = mb_strlen($p, 'utf-8');
		if ($plen < $rlen || $plen == 0 || $rlen == 0) {
			return false;
		}
		$pos = mb_strpos($path, $root, 0, 'utf-8');
		if ($pos === false || $pos !== 0) {
			return false;
		}
		if ($plen == $rlen) {
			return true;
		} else {
			$c = mb_substr($p, $rlen, 1, 'utf-8');
			return ($c == '/' ? true : false);
		}
		return false;
	}

	public static function get($path, $root = null, $expanded = false) {
		if ($root !== null) {
			if (!bf_path::inside($path, $root, $expanded)) {
				return false;
			}
		}
		return @file_get_contents($path);
	}

	public static function put($path, $content, $root = null, $expanded = false) {
		if ($root !== null) {
			if (!bf_path::inside(dirname($path), $root, $expanded)) {
				return false;
			}
		}
		return (@file_put_contents($path, $content, LOCK_EX) === false ? false : true);
	}

	public static function ls($path, $root = null, $expanded = false) {
		if ($root !== null) {
			if (!bf_path::inside($path, $root, $expanded)) {
				return array();
			}
		}
		$dirs = array();
		$files = array();
		foreach (scandir($path) as $fn) {
			if (in_array($fn, array('.', '..'))) {
				continue;
			}
			$fullname = bf_path::concat($path, $fn);
			if (is_dir($fullname)) {
				$dirs[] = $fn;
			} else {
				$files[] = $fn;
			}
		}
		$res = array();
		foreach ($dirs as $fn) {
			$res[] = (object) array('name' => $fn, 'directory' => true);
		}
		foreach ($files as $fn) {
			$res[] = (object) array('name' => $fn, 'directory' => false);
		}
		return $res;
	}
}

?>